/**
 * @Author: zhongyang
 * @Date: 2022/6/27 16:35
 */

package main

import "fmt"

/**
11_桥接模式
概念：将抽象部分与它的实现部分分离，使它们都可以独立地变化。
这种模式涉及到一个作为桥接的接口，使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

使用方法：首先应该识别出一个类所具有的两个独立变化的维度，将它们设计为两个独立的继承等级结构，为两个维度都提供抽象层，并建立抽象耦合。

tips：发送紧急信息和常用信息为一个维度，使用SMS形式或Email形式发送为一个维度，这两个维度不同，所以分别在不同的抽象层。
*/

type MessageImplementer interface {
	send(text, to string)
}

type MessageSMS struct {
}

func (m *MessageSMS) send(text, to string) {
	fmt.Printf("SMS信息：[%v]；发送到：[%v]\n", text, to)
}

func ViaSMS() *MessageSMS {
	return &MessageSMS{}
}

type MessageEmail struct {
}

func (m *MessageEmail) send(text, to string) {
	fmt.Printf("Email信息：[%v]；发送到：[%v]\n", text, to)
}

func ViaEmail() *MessageEmail {
	return &MessageEmail{}
}

// 发送信息二次封装
type AbstractMessage interface {
	SendMessage(text, to string)
}

// 普通信息
type CommonMessage struct {
	method MessageImplementer
}

func NewCommonMessage(method MessageImplementer) *CommonMessage {
	return &CommonMessage{method: method}
}

func (c *CommonMessage) SendMessage(text, to string) {
	c.method.send(text, to)
}

// 紧急信息
type UrgencyMessage struct {
	method MessageImplementer
}

func NewUrgencyMessage(method MessageImplementer) *UrgencyMessage {
	return &UrgencyMessage{method: method}
}

func (u *UrgencyMessage) SendMessage(text, to string) {
	u.method.send(fmt.Sprintf("【紧急信息】%v", text), to)
}

func main() {
	var m AbstractMessage
	m = NewCommonMessage(ViaSMS())
	m.SendMessage("你需要喝一杯咖啡吗", "阿香")

	m = NewCommonMessage(ViaEmail())
	m.SendMessage("好滴", "强哥")

	m = NewUrgencyMessage(ViaSMS())
	m.SendMessage("晚上桥头见", "阿香")

	m = NewUrgencyMessage(ViaEmail())
	m.SendMessage("不见不散", "强哥")
}
